#ifndef RTP_PARSE_FEEDBACK_RTP_NACK_H
#define RTP_PARSE_FEEDBACK_RTP_NACK_H

#include "rtp/FeedbackItem.h"
#include "rtp/Feedback.h"
#include "rtp/FeedbackRtp.h"
#include "utils.h"

namespace Rtp {
    namespace Rtcp {
        class FeedbackRtpNackItem: public FeedbackItem {
        public:
            struct Header {
                uint16_t packetId;
                uint16_t lostPacketBitmask;
            };
        public:
            static const size_t HeaderSize { 4 };
            static const FeedbackRtp::MessageType messageType { FeedbackRtp::MessageType::NACK };

        public:
            explicit FeedbackRtpNackItem(Header *header) : header(header) {}

            explicit FeedbackRtpNackItem(FeedbackRtpNackItem *item): header( item->header) {}

            FeedbackRtpNackItem(uint16_t packetId, uint16_t lostPacketBitmask);
            ~FeedbackRtpNackItem() override = default;

            uint16_t GetPacketId() const {
                return uint16_t{ ntohs(this->header->packetId) };
            }

            uint16_t GetLostPacketBitmask() const {
                return uint16_t{ ntohs(this->header->lostPacketBitmask) };
            }

            size_t CountRequestedPackets() const {
                return Utils::Bits::CountSetBits(this->header->lostPacketBitmask) + 1;
            }
        public:
            void Dump() const override;
            size_t Serialize(uint8_t* buffer) override;
            size_t GetSize() const override {
                return FeedbackRtpNackItem::HeaderSize;
            }
        private:
            Header *header { nullptr };
        };

        using FeedbackRtpNackPacket = FeedbackRtpItemsPacket<FeedbackRtpNackItem>;
    }
}

#endif